home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / Exploit and vulnerability / hoobie / lpr_bugs.txt < prev    next >
Encoding:
Text File  |  2001-11-06  |  8.1 KB  |  224 lines

  1.  
  2. While working of a port of "lpr/lpd" to Windows95 I noticed some
  3. weaknesses in the implementation of the LPR protocol.   Mostly it
  4. appears to affect BSD based UNIX's.  I found it using the source for
  5. BSD4.4, and tested it on "Linux Slackware 2.2.0".  I have also tested it
  6. on AIX 4.1.5 and it seems to be OK.  Unfortunately, (or Fortunately
  7. depending on how you look at it), I only have access to these two
  8. operating systems.
  9.  
  10. Explaining this assumes that you are familiar with [RFC-1179 Line Pinter
  11. Daemon Protocol].  If you are not familiar or have not read it, it may
  12. be obtained via FTP from        ftp://nic.ddn.mil/rfc/rfc1179.txt
  13.  
  14. The possibilities are as follows:
  15. 1.) Obtaining hard (or possibly soft) copies of any file on the system.
  16. 2.) Deleting any file on the system.
  17. 3.) Creating a file on the system.
  18. 4.) Mail bombing.
  19.  
  20. There are a few requirements that need to be met in order to perform
  21. these actions.
  22. 1.) Must be 'root' on the source machine.
  23. NOTE:  Under Windows95 the user already has 'root' status.  This means
  24. that anyone on a Win95 box
  25. can bind network sockets to the reserved ports.
  26. 2.) Must have or obtain permission to print to the target machine.
  27. Usually machines on the same network will have permission to print to
  28. each other, but that may not always be the case.
  29. 3.) Must have or obtain access to the target printer.  Otherwise how
  30. will you get your printout?
  31.  
  32. HOW IT WORKS...
  33.  
  34. When lpd sends a file to a remote machine it creates a control file used
  35. to instruct the remote machine on how to process the incoming print
  36. job.   These commands are outlined in [RFC-1179].  It is the
  37. implementation of the control commands that provide the weakness.
  38.  
  39. 1.) Obtaining hard (or possibly soft) copies of any file on the system.
  40. The control command 'f' causes a file to be printed as text.
  41.  
  42. The syntax is: f filename [LF]
  43.  
  44. Therefore, by inserting the line:  "f/etc/shadow" into the control file
  45. you will cause the
  46. Shadow password file to be printed.  (Hard copy)
  47.  
  48. If the print queue points to a network printer then it would be possible
  49. to capture the packets. (Soft copy)
  50.  
  51. 2.) Delete any file on the system.
  52. The control command 'U' instructs the remote machine to "unlink" the
  53. file upon completion of the job.
  54.  
  55. The syntax is: U filename [LF]
  56.  
  57. Therefore, by inserting the line: "U/vmlinuz" into the control file you
  58. will cause the Linux kernel to be
  59. removed from the file system.
  60.  
  61. 3.) Create a file on the remote system.
  62. This is a little trickier, in that BSD4.4 takes the filename that you
  63. specify and appends its view of the calling machine's hostname to it.
  64. However, BSD4.4 starts at the sixth character.
  65.  
  66. The syntax is 2 size [SP] filename [LF].  Where '2' is the octet 2 not
  67. the character, size is the size of the file in bytes, filename is ...
  68. (DUH).
  69.  
  70. - From RECVJOB.C
  71.                 case '\2':      /* read cf file */
  72.                         size = 0;
  73.                         while (*cp >= '0' && *cp <= '9')
  74.                                 size = size * 10 + (*cp++ - '0');
  75.                         if (*cp++ != ' ')
  76.                                 break;
  77.                         /*
  78.                          * host name has been authenticated, we use our
  79.                          * view of the host name since we may be passed
  80.                          * something different than what gethostbyaddr()
  81.                          * returns
  82.                          */
  83. HERE ----------->  strcpy(cp + 6, from);
  84.                         strcpy(tfname, cp);
  85.                         tfname[0] = 't';
  86.                         if (!chksize(size)) {
  87.                                 (void) write(1, "\2", 1);
  88.                                 continue;
  89.                         }
  90.                         if (!readfile(tfname, size)) {
  91.                                 rcleanup(0);
  92.                                 continue;
  93.                         }
  94.                         if (link(tfname, cp) < 0)
  95.                                 frecverr("%s: %m", tfname);
  96.                         (void) unlink(tfname);
  97.                         tfname[0] = '\0';
  98.                         nfiles++;
  99.                         continue;
  100.  
  101. The result is this:
  102.  
  103.         /rc             becomes         /rc
  104.         /etc/passwd     becomes         /etc/passwd.www.yourhost.com
  105.  
  106. This is accomplished by using the printer command of '2' (receive
  107. control file)
  108.  
  109. Therefore by sending the printer command '2/rc'  and then sending our
  110. file, we have created a file in the root directory called 'rc'.
  111. By sending '2/home/yourfriend/somefile' and the your file you will have
  112. sent somefile to yourfriend ... and even put it in their home
  113. directory.  Of course it will have the name somefile.www.yourhost.com,
  114. but he got it none the less.
  115.  
  116. 4.) Mail bombing.
  117. The control command 'M' instructs lpd to mail the user when the job is
  118. finished.
  119.  
  120. The syntax is: M username [LF]
  121.  
  122. Therefore by adding the line: "Mjoeuser@www.somewhere.com"  you will
  123. cause joeuser to receive mail notification about the print job.   By
  124. adding several thousand of these lines, well you get the idea.
  125.  
  126. SOLUTIONS ???
  127. These holes are due to the implementation of the lpr protocol and the
  128. fact that lpd runs as root.  I am sure that there may be many solutions
  129. to this, but At first glance I think that by checking for a '/' in the
  130. filenames would cause the program to react when someone tries to print
  131. files from outside of the queue directory.
  132.  
  133. As far as the mail bomb, maybe by checking the destination host with
  134. lpd's view of the caller, but that wouldn't allow for someone to print
  135. from one account and get the mail at another.  IE the boss getting
  136. notices when the report is finished.
  137.  
  138. Let me know if I have miss-stated something.
  139.  
  140.                                 Bennett
  141.  
  142. ---------------------------------------------------------------------------
  143.  
  144.  
  145. > 1.) Obtaining hard (or possibly soft) copies of any file on the system.
  146. > 2.) Deleting any file on the system.
  147. > 3.) Creating a file on the system.
  148. > 4.) Mail bombing.
  149.  
  150. 5.) Overflow at least one buffer from the network; this is just
  151. above the "print any file" part of recvjob.c:
  152.  
  153.                 cp = line;
  154.                 do {
  155.                         if ((size = read(1, cp, 1)) != 1) {
  156.                                 if (size < 0)
  157.                                         frecverr("%s: Lost connection",printer);
  158.                                 return(nfiles);
  159.                         }
  160.                 } while (*cp++ != '\n');
  161.  
  162. Consequences aren't really obvious, but you may be able to do
  163. nasty things.
  164.  
  165. Will we ever get rid of gets()?  (lpd source tree is from some
  166. recent RedHat distribution.)
  167.  
  168.  
  169. ----------------------------------------------------------------------------
  170.  
  171. >
  172. >On October 02 1997, Bennett Samowich wrote:
  173. >
  174. >> 1.) Obtaining hard (or possibly soft) copies of any file on the system.
  175. >> 2.) Deleting any file on the system.
  176. >> 3.) Creating a file on the system.
  177. >> 4.) Mail bombing.
  178. >
  179. >5.) Overflow at least one buffer from the network; this is just
  180. >above the "print any file" part of recvjob.c:
  181. >
  182. >                cp = line;
  183. >                do {
  184. >                        if ((size = read(1, cp, 1)) != 1) {
  185. >                                if (size < 0)
  186. >                                        frecverr("%s: Lost connection",printer);
  187. >                                return(nfiles);
  188. >                        }
  189. >                } while (*cp++ != '\n');
  190. >
  191. >
  192. >Consequences aren't really obvious, but you may be able to do
  193. >nasty things.
  194. >
  195. >Will we ever get rid of gets()?  (lpd source tree is from some
  196. >recent RedHat distribution.)
  197.  
  198. Here's another one from common_source/common.c
  199.     while ((c = getc(cfp)) != '\n') {
  200.         if (c == EOF)
  201.             return(0);
  202.         if (c == '\t') {
  203.             do {
  204.                 *lp++ = ' ';
  205.                 linel++;
  206.             } while ((linel & 07) != 0);
  207.             continue;
  208.         }
  209.         *lp++ = c;
  210.         linel++;
  211.     }
  212.     *lp++ = '\0';
  213.     return(linel);
  214.  
  215. A fix would appear to be to make the while like this:
  216.     while ((c = getc(cfp)) != '\n' && linel < BUFSIZ-8) {
  217.  
  218. Why BUFSIZ-8?
  219. leave space for tab expansion in inner do loop. It still should be
  220. a plenty long enough buffer. Or, add another check for linel in
  221. inner do loop.
  222.  
  223. ----------------------------------------------------------------------------
  224.